<?php

namespace App\Http\Controllers;

use App\Http\Models\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class LoginController extends Controller
{
    // 内测成员列表
    const PRIVATE_USERS = [
        '67AC8B054FFC50F503A8C9EA1101C442' => 1,
        'CAFB7F2B50802EBFDF4C06C8883CEBB2' => 20210106,
        '0CC4F69A6EA7A6F8B60C74F30EF5C88E' => 20210106
    ];
    public function __construct()
    {

    }

    public function login(Request $req) {
        $start = microtime(true);
        $lyf_code = trim($req->input('lyfCode'));
        if(!$lyf_code) return $this->error('无效的登录请求');

        $test = $req->input('testenv');
        if($test == '111') $env = 'local';
        else $env = 'online';

        $step1 = microtime(true);
        file_put_contents('/tmp/login_record.log', date('Y-m-d H:i:s')." ========================== ".$lyf_code . "\n", FILE_APPEND);

        $device_id = trim($req->input('device_id'));
        if(!$device_id) return $this->error('无效的登录设备');

        $nickname = '';
        $avatar = 'https://static3.laiyifen.com/files/user/image/head/bef5be87438e43d5aa1d0a59cd72a36b.jpg';
        $is_vip = false;
        $new_user = 0;

        if($env == 'online') {
            file_put_contents('/tmp/login_record.log', "start get platform info ...\n", FILE_APPEND);
            $pstr = json_encode(['lyfcode' => $lyf_code]);
            $uri = '/lyf-user/auth/info';
            $url = env('ORIGIN_API') . $uri;
            $sig_time = \App\Http\Controllers\Controller::now();
            $sig = base64_encode(hash_hmac(
                "sha1",
                "POST\n" .
                $uri . "\n" .
                "x-co-client:" . env('APPID') . "\n" .
                "x-co-timestamp:" . $sig_time . "\n" .
                strtoupper(md5($pstr)),
                env('APPSECRET'),
                true
            ));
            $headers = [
                'Content-Type:application/json',
            ];
            $headers[] = 'X-Co-Client:' . env('APPID');
            $headers[] = 'X-Co-TimeStamp:' . $sig_time;
            $headers[] = 'X-Co-Sign:' . $sig;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $pstr);
            $output = curl_exec($ch);
            curl_close($ch);
            $login_result = json_decode($output, true);

            $step2 = microtime(true);
            file_put_contents('/tmp/login_record.log', "get info: ".$output."    spend time: ".round($step2-$step1, 5)."\n", FILE_APPEND);

            if (!isset($login_result['code']) || $login_result['code'] != '0') {
                file_put_contents('/tmp/login_error.log', date('Y-m-d H:i:s')."==========================================\n".$lyf_code."\n".$output."\n\n", FILE_APPEND);
                return isset($login_result['msg']) ? $this->error($login_result['msg']) : $this->error(json_encode($login_result));
            } else {
                // 员工限制
                // if($login_result['data']['lyfuid'] != '67AC8B054FFC50F503A8C9EA1101C442' && $login_result['data']['employee'] !== true) {
                // if( env('APP_ENV') != 'dev' && !isset( self::PRIVATE_USERS[$login_result['data']['lyfuid']] ) && $login_result['data']['employee'] !== true ) {
                //     return $this->error('不在内测名单内，敬请期待~');
                // }
                $openid = $login_result['data']['lyfuid'];
                $nickname = $login_result['data']['nickName'];
                $avatar = $login_result['data']['headUrl'];
                if(isset($login_result['data']['paidMember']) && $login_result['data']['paidMember'] === true) {
                    $is_vip = true;
                }
                if($login_result['data']['newUser'] === true) {
                    $new_user = 1;
                }
            }
        } else {
            $step2 = microtime(true);
            // local 环境测试
            $openid = $lyf_code;
        }

        $get_user = DB::table('users')->where('openid', $openid)->first();

        $step3 = microtime(true);
        file_put_contents('/tmp/login_record.log', "find user: ".(isset($get_user['id']) ? json_encode($get_user) : 'new user')."    spend time: ".round($step3-$step2, 5)."\n", FILE_APPEND);

        $now = time();
        $api_token = md5($openid.microtime().mt_rand(10000,99999));

        // 微信头像替换
        // str_replace('www','http://www',$str);
        if(strstr($avatar, 'thirdwx.qlogo.cn') || strstr($avatar, 'wx.qlogo.cn')) {
            $avatar .= '?aaa=aa.jpg';
        }
        //创建新用户
        if(!isset($get_user['id'])) {
            try {
                // 创建鸭子
                $duck_id = DB::table('ducks')->insertGetId([]);
                if(!$duck_id) throw new \Exception('鸭子创建失败');

                $uinfo = [
                    'openid' => $openid,
                    'duckId' => $duck_id,
                    'createTime' => $now,
                    'nickName' => $nickname,
                    'star' => 0,
                    'totalStar' => 0,
                    'level' => 0,
                    'avatar' => $avatar,
                    'exp' => 0,
                    'fodder' => config('game.cfg.BaseInitFodderNum'),
                    'newbie' => 1,
                    'newUser' => $new_user,
                    'device_id' => $device_id,
                ];
                $uid = DB::table('users')->insertGetId($uinfo);
                if (!$uid) return $this->error('创建用户失败');
                $uinfo['uid'] = $uid;
                $uinfo['newbie'] = 0;

                //创建apitoken
                $new_apitoken = DB::table('api_token')->insert([
                    'apitoken' => $api_token,
                    'uid' => $uid,
                    'expire' => $now + 259200,
                ]);
                if (!$new_apitoken) return $this->error('登录凭证生成失败');

                //创建id映射关系
                DB::table('platformships')->insert(['openid' => $openid, 'userId' => $uid]);
            } catch(\Exception $e) {
                return $this->error('创建用户失败.'.$e->getMessage());
            }

            $step4 = microtime(true);
            file_put_contents('/tmp/login_record.log', "create user: ".json_encode($uinfo)."    spend time: ".round($step4-$step3, 5)."\n", FILE_APPEND);
        }
        //老用户登录
        else {
            $uid = $get_user['id'];
            $uinfo = $get_user;
            $uinfo['uid'] = $uinfo['id'];
            // 刷新token
            DB::table('api_token')->where('uid', $uid)->update(['apitoken'=>$api_token, 'expire'=>$now+259200]);
            $set = [];

            // 刷新昵称和头像
            if( $uinfo['nickName'] != $nickname && !empty( $nickname ) ) {
                $uinfo['nickName'] = $nickname;
                $set['nickName'] = $nickname;
            }

            if( $uinfo['avatar'] != $avatar && !empty( $avatar ) ) {
                $uinfo['avatar'] = $avatar;
                $set['avatar']   = $avatar;
            }
            if($device_id) {
                $set['device_id'] = $device_id;
            }
            if(!empty($set)) {
                DB::table('users')->where('id', $uinfo['id'])->update($set);
            }

            $step4 = microtime(true);
            file_put_contents('/tmp/login_record.log', "update user    spend time: ".round($step4-$step3, 5)."\n", FILE_APPEND);
        }

        // 统计
        Redis::INCR('DAY_PV:'.date('Y-m-d'), 1);
        Redis::SADD('DAY_UV:'.date('Y-m-d'), $uid);

        // 黑金会员修改任务状态
        if($is_vip === true) {
            Task::setProgress($uid, 601, 1);
            Task::setProgress($uid, 2017, 1);
        }

        // 读取季节
        $now_season = 1;
        $invite_link = '';
        $config_data = Redis::HGETALL('CONFIG_DATA');
        foreach($config_data as $c) {
            $c_arr = json_decode($c, true);
            if($c_arr['Name'] == 'season') {
                $now_season = $c_arr['Val'];
            }
            if($c_arr['Name'] == 'invite_link') {
                $invite_link = $c_arr['Val'];
            }
        }

        // 处理好友关系
        $friend_openids = [];
        #do {
            $page = 1;
            $uri = '/im-app-api/friends';
            $friend_list = curl_call($uri, ['lyfuid' => $uinfo['openid'], 'page' => $page, 'pageSize' => 10 ]);
            #if(empty($friend_list['data']['authorization']) && empty($friend_list['data']['unauthorization'])) break;
            if(isset($friend_list['data']['authorization'])) {
                foreach($friend_list['data']['authorization'] as $fdata) {
                    $friend_openids[] = $fdata['lyfuid'];
                }
            }
        #} while($count++ < 5);

        // 获取好友openid列表的游戏好友
        if(!empty($friend_openids)) {
            $get_uids = DB::table('platformships')->whereIn('openid', $friend_openids)->get();
            if(!empty($get_uids)) {
                $uids = [];
                foreach($get_uids as $fuid) {
                    $uids[] = $fuid['userId'];
                }
                $get_fuinfos = DB::table('users')->where('duckId','>',0)->whereIn('id', $uids)->get();
                if(!empty($get_fuinfos)) {
                    $farr = [];
                    foreach($get_fuinfos as $fuinfo) {
                        $farr[] = $fuinfo['id'] . '^' . $fuinfo['star'] . '^' . $fuinfo['totalStar'] . '^' . $fuinfo['nickName'] . '^' . $fuinfo['avatar'] . '^' . $fuinfo['duckId'];
                    }
                    Redis::SET('LyfenFriend:'.$uid, join(',', $farr));
                }
            }
        }

        $step5 = microtime(true);
        file_put_contents('/tmp/login_record.log', "get season    spend time: ".round($step5-$step4, 5)."\n", FILE_APPEND);

        // 获取关注状态
        $att = Redis::GET('LyfenUser:Attention:'.$uid);
        if($att != 1) $att = 2;

        $step8 = microtime(true);
        file_put_contents('/tmp/login_record.log', "get attention status.    spend time: ".round($step8-$step5, 5)."\n", FILE_APPEND);

        // 判断等级任务
        $level_tasks  = DB::table('game_tasks')->where('type', config('game.cfg.TaskTypeLvup'))->get();
        $get_my_tasks = DB::table('user_task')->where('uid', $uid)->get();
        $my_tasks = [];
        foreach($get_my_tasks as $mt) {
            $my_tasks[$mt['tid']] = $mt;
        }
        $min_level_need = 9999;
        // $select_tid = null;
        foreach($level_tasks as $task_conf) {
            if(isset($my_tasks[$task_conf['id']]) && $my_tasks[$task_conf['id']]['status'] == config('game.cfg.TaskStatusReceived')) continue;
            if($task_conf['cond'] < $min_level_need) {
                $min_level_need = $task_conf['cond'];
            }
        }

        $step9 = microtime(true);
        file_put_contents('/tmp/login_record.log', "process level tasks.    spend time: ".round($step9-$step8, 5)."\n==================  ALL DONE, total spend: ".round($step9-$step1, 5)."  ==================\n\n", FILE_APPEND);

        // 检查任务红点
        Task::checkReddot( $uid );

        return $this->result([
            'uid' => $uid,
            "user" => $uinfo,
            'conf' => [
                'perFeedConsume' => config('game.cfg.BasePerFeedConsume'),
                'perDigestionTime' => config('game.cfg.BasePerDigestionTime')*1000,
                'perProductStarFeedCount' => config('game.cfg.BasePerProductStarFeedCount'),
                'perLvupStarNum' => config('game.cfg.BasePerLvupStarNum'),
                'maxStorageFodderNum' => config('game.cfg.BaseMaxStorageFodderNum'),
                'baseFodderNum' => config('game.cfg.BaseInitFodderNum'),
                'scene' => $now_season,
                'invite_link' => $invite_link,
		        'share_url' => 'https://api.laiyifen.com/duckery/web/share.html',
            ],
            'token' => $api_token,
            'icon_url' => 'https://www.bkdau.cn/damai/lyfen/bannerUpload/icon_20201124202535_850990.png',
            'attention' => $att,
            'process_time' => microtime(true) - $start,
            'next_level_reward' => $min_level_need,
        ]);
    }

    public function log(Request $req) {
        $log = $req->input('data');
        file_put_contents('/tmp/front_log.log', date('Y-m-d H:i:s')." ============================\n".$log."\n\n", FILE_APPEND);
        return $this->result([1]);
    }
}
